package cqrtplm.aop;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.hustcad.plm.pdm.ec.module.dto.TyplmChangeIssueDTO;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import cqrtplm.common.CommonService;
import cqrtplm.constant.RTErrorCodeEnum;
import cqrtplm.entity.PreventErrorCorrectionDO;
import cqrtplm.mapper.PreventErrorCorrectionMapper;
import cqrtplm.mapper.RTTypeClassMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.format.DateTimeParseException;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Aspect
@Component
@Slf4j
public class PreventErrorCorrectionAOP {
    @Resource
    private PreventErrorCorrectionMapper preventErrorCorrectionMapper;
    @Resource
    private SnowflakeIdComponent snowflakeIdComponent;
    @Resource
    private CommonService commonService;
    @Value("${ipd.base.url:http://127.0.0.1:9588}")
    private String ipdUrl;

    @SneakyThrows
    @Around("execution(* com.hustcad.plm.pdm.ec.service.TyplmChangeIssueService.createChangeIssueAndEcLink(..))")
    @Transactional(rollbackFor = Exception.class)
    public Object createChangeIssueAop(ProceedingJoinPoint joinPoint){
        TyplmChangeIssueDTO changeIssueDTO = (TyplmChangeIssueDTO) joinPoint.getArgs()[0];
        String containerotype = changeIssueDTO.getContainerotype();
        // 创建问题报告时，将项目属性同步到表单中
        if(TableTypeConstrant.TY_PROJECT_TYPE.equals(containerotype)){
//            synchronizeProjectProperties(changeIssueDTO);
        }
        //创建问题报告时 将表单数据插入预防纠错表
//        insertPreventErrorCorrection(changeIssueDTO);
        log.info("表单信息：{}", changeIssueDTO.getFormData());
        return joinPoint.proceed();
    }

    private void insertPreventErrorCorrection(TyplmChangeIssueDTO changeIssueDTO) {
        String formData = changeIssueDTO.getFormData();
        if (StringUtils.isNotBlank(formData) && StringUtils.isNotEmpty(formData)) {
            try {
                //将表单转换为JSON对象
                JSONObject formJson = JSON.parseObject(formData);
                // 获取具体的字段并添加至实体类中
                PreventErrorCorrectionDO preventErrorCorrectionDO = new PreventErrorCorrectionDO();
                //设置mid
                preventErrorCorrectionDO.setMid(String.valueOf(snowflakeIdComponent.getInstance().nextId()));
                //设置问题报告编号
//                preventErrorCorrectionDO.setObjectNumber(ObjectNumber);
//                //设置问题类型
//                preventErrorCorrectionDO.setTypeOid(changeIssueDTO.getTypeoid());
                //设置问题类型名称
                preventErrorCorrectionDO.setType(formJson.getString("Type"));
                //项目编号
                preventErrorCorrectionDO.setProjectNo(getAndValidateField(formJson,"ProjectNo"));
                //终端机型
                preventErrorCorrectionDO.setTerminalModel(getAndValidateField(formJson,"TerminalModel"));
                //动力型号
                preventErrorCorrectionDO.setPowerModel(getAndValidateField(formJson,"PowerModel"));
                //零部件名称
                preventErrorCorrectionDO.setComponentName(getAndValidateField(formJson,"ComponentName"));
                //图样代号
                preventErrorCorrectionDO.setPatternCode(getAndValidateField(formJson,"PatternCode"));
                //设置发生日期
                preventErrorCorrectionDO.setOccurrenceDate(getAndValidateDateField(formJson,"OccurrenceDate"));
                //发生阶段
                preventErrorCorrectionDO.setOccurrenceStage(getAndValidateField(formJson,"OccurrenceStage"));
                //发生环境
                preventErrorCorrectionDO.setOccurrenceEnvironment(getAndValidateField(formJson,"OccurrenceEnvironment"));
                //重要度
                preventErrorCorrectionDO.setImportance(getAndValidateField(formJson,"Importance"));
                //提出人
              //  preventErrorCorrectionDO.setProposer(getUserName(formJson,"Proposer"));
                //提出人ID
              //  preventErrorCorrectionDO.setProposerID(getUserNameID(formJson,"Proposer"));
                //vin
              //  preventErrorCorrectionDO.setVin(getAndValidateField(formJson,"VIN"));
                //不良现象描述
                preventErrorCorrectionDO.setPhenomenonDescription(getAndValidateField(formJson,"PhenomenonDescription"));
                //原因解析描述
                preventErrorCorrectionDO.setAnalysisDescription(getAndValidateField(formJson,"AnalysisDescription"));
                //对策（暂定对策）
                preventErrorCorrectionDO.setTentativeCountermeasures(getAndValidateField(formJson,"TentativeCountermeasures"));
                //源流改善
                preventErrorCorrectionDO.setSourceImprovement(getAndValidateField(formJson,"SourceImprovement"));
                //对策（恒久对策）
                preventErrorCorrectionDO.setLongCountermeasures(getAndValidateField(formJson,"LongCountermeasures"));
                //供应商
                preventErrorCorrectionDO.setSupplier(getAndValidateField(formJson,"Supplier"));
                //问题类型
                preventErrorCorrectionDO.setProblemType(getAndValidateField(formJson,"ProblemType"));
                //关闭阶段
                preventErrorCorrectionDO.setClosingStage(getAndValidateField(formJson,"ClosingStage"));
                //承接人
                preventErrorCorrectionDO.setPersonResponsible(getUserName(formJson,"PersonResponsible"));
                //承接人ID
             //   preventErrorCorrectionDO.setPersonResponsibleID(getUserNameID(formJson,"PersonResponsible"));
                //反馈部门
                preventErrorCorrectionDO.setDepartment(getAndValidateField(formJson,"FeedbackDepartment"));
                //反馈人
                preventErrorCorrectionDO.setFeedbackPerson(getUserName(formJson,"FeedbackPerson"));
                //反馈人ID
           //     preventErrorCorrectionDO.setFeedbackPersonID(getUserNameID(formJson,"FeedbackPerson"));
                //计划完成日期
                preventErrorCorrectionDO.setPlannedDate(getAndValidateDateField(formJson,"PlannedDate"));
                //确认方式
                preventErrorCorrectionDO.setConfirmationMethod(getAndValidateField(formJson,"ConfirmationMethod"));
                //确认进度
                preventErrorCorrectionDO.setProgressConfirmation(getAndValidateField(formJson,"ProgressConfirmation"));
                //是否关闭
                preventErrorCorrectionDO.setIsClose(getAndValidateField(formJson,"IsClose"));
                //确认日期
                preventErrorCorrectionDO.setConfirmDate(getAndValidateDateField(formJson,"ConfirmDate"));
                //确认人
                preventErrorCorrectionDO.setConfirmationPerson(getUserName(formJson,"ConfirmationPerson"));
                //确认人ID
          //      preventErrorCorrectionDO.setConfirmationPersonID(getUserNameID(formJson,"ConfirmationPerson"));
                //备注
                preventErrorCorrectionDO.setRemark(getAndValidateField(formJson,"Remark"));
                //项目开发令
           //     preventErrorCorrectionDO.setDevOrder(getAndValidateField(formJson,"ProjectDevelopmentOrder"));
                //项目名称
             //   preventErrorCorrectionDO.setProjectName(getAndValidateField(formJson,"ProjectName"));
                //开发阶段
            //    preventErrorCorrectionDO.setDevelopmentPhase(getAndValidateField(formJson,"DevelopmentPhase"));
                //项目组长
            //    preventErrorCorrectionDO.setProjectLeader(getAndValidateField(formJson,"ProjectLeader"));

                log.info("表单数据: {}", preventErrorCorrectionDO);
                //插入表单数据到数据库
                preventErrorCorrectionMapper.batchInsertPrevent(Collections.singletonList(preventErrorCorrectionDO));
            } catch (Exception e) {
                log.error("插入表单失败", e);
            }
        }
    }


    public static String getAndValidateField(JSONObject formJson, String fieldName) {
        if (!formJson.containsKey(fieldName)) {
            throw new IllegalArgumentException("表单数据中缺少 " + fieldName + " 字段");
        }
        String value = formJson.getString(fieldName);
        if (value == null || value.isEmpty()) {
            return null;
        }
        return value;
    }


    // 工具方法：获取并验证日期字段
    public static Date getAndValidateDateField(JSONObject formJson, String fieldName) {
        if (!formJson.containsKey(fieldName)) {
            throw new IllegalArgumentException("表单数据中缺少 " + fieldName + " 字段");
        }
        Date value =formJson.getDate(fieldName);
        if (value == null) {
            return null;
        }
        try {
            return value;
        } catch (DateTimeParseException e) {
            throw new IllegalArgumentException("日期格式错误: " + value);
        }
    }


    public static String getUserName(JSONObject formJson, String fieldName) {
        String jsonArrayStr = formJson.getString(fieldName);
        if (jsonArrayStr == null || jsonArrayStr.isEmpty()) {
            return null;
        }
        String firstChar=jsonArrayStr.substring(0,1);
        if (!(firstChar.equals("{") || firstChar.equals("["))){
            return jsonArrayStr;
        }
        JSONArray array = JSON.parseArray(jsonArrayStr);
        if (array == null || array.isEmpty()) {
            return null;
        }
        JSONObject userObj = array.getJSONObject(0);
        return userObj.getString("displayName");
    }

    @Resource
    private RTTypeClassMapper rtTypeClassMapper;

    /**
     * 创建问题报告时，将项目属性同步到表单中
     * @return
     * @throws Throwable
     */
    public void synchronizeProjectProperties(TyplmChangeIssueDTO changeIssueDTO) {
        try {
            String url = ipdUrl + "/api/v1/dashboard/getProjectDetailByOID";
            UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromHttpUrl(url)
                    .queryParam("oid", changeIssueDTO.getContaineroid());
            String responseData = commonService.sendGetRequestToIPD(urlBuilder.toUriString());
            log.info("项目信息=========>: {}", responseData);
            JSONObject responseJson = JSONObject.parseObject(responseData);
            JSONObject data = responseJson.getJSONObject("data");
            if (data!=null && data.containsKey("ibaAttribute") && data.getJSONObject("ibaAttribute")!=null) {
                Map<String, List<String>> ibaAttributeMap = JSON.parseObject(
                        data.getJSONObject("ibaAttribute").toJSONString(),
                        new TypeReference<Map<String, List<String>>>() {}
                );
                String formData = changeIssueDTO.getFormData();
                JSONObject formJson = JSON.parseObject(formData);
                if (Objects.nonNull(formJson)){
                    String typeName = rtTypeClassMapper.queryTypeNameByOid(String.valueOf(changeIssueDTO.getTypeoid()));
                    if(StringUtils.isNotBlank(typeName) && StringUtils.isNotEmpty(typeName)){
                        if(typeName.contains("Issue") || typeName.contains("unitIssue")){
                            formJson.put("ProjectDevelopmentOrder",
                                         getIbaAttrValue(ibaAttributeMap, "ProjectDevelopmentOrder"));
                            formJson.put("ProjectName", data.getString("name"));
                            formJson.put("ProjectNo", data.getString("projectNumber"));
                            formJson.put("TerminalModel", getIbaAttrValue(ibaAttributeMap, "productType"));
                            formJson.put("ProjectLeader", getProjectLeader(changeIssueDTO));
                            formJson.put("Type", data.getString("category"));
                        }else if(typeName.contains("Risk")){
                            formJson.put("ProjectName", data.getString("name"));
                            formJson.put("ProjectNumber", data.getString("projectNumber"));
                            formJson.put("ProjectLeader", getProjectLeader(changeIssueDTO));
                        }
                    }
                    log.info("==================>:{}",formJson);
                    changeIssueDTO.setFormData(formJson.toJSONString());
                }
            }
        } catch (IOException e) {
            throw RTErrorCodeEnum.NOT_FOUND_FILE_TEMPLATE.getException(e.getMessage());
        }
    }

    private String getProjectLeader(TyplmChangeIssueDTO changeIssueDTO) throws  IOException{
        String url = ipdUrl+ "/api/v1/ProjectTeam/queryContainerTeamByContainer";
        UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromHttpUrl(url)
                .queryParam("containerOID", changeIssueDTO.getContaineroid())
                .queryParam("containerOTYPE", changeIssueDTO.getContainerotype());
        String responseData = commonService.sendGetRequestToIPD(urlBuilder.toUriString());
        JSONObject responseJson = JSONObject.parseObject(responseData);
        JSONArray data = responseJson.getJSONArray("data");
        for (int i = 0; i < data.size(); i++) {
            JSONObject jsonObject = data.getJSONObject(i);
            if("PROJECT DIRECTOR".equals(jsonObject.getString("type"))){
                JSONArray children = jsonObject.getJSONArray("children");
                if(CollUtil.isNotEmpty(children)){
                    return children.stream()
                            .map(obj -> (JSONObject) obj)
                            .map(child -> child.getString("fullName"))
                            .filter(StringUtils::isNotBlank)
                            .collect(Collectors.joining(","));
                }
            }
        }
        return "";
    }

    private static String getIbaAttrValue(Map<String, List<String>> ibaAttributeMap, String key) {
        if(ibaAttributeMap.containsKey(key)){
            List<String> strings = ibaAttributeMap.get(key);
            if(CollUtil.isNotEmpty(strings)){
                return strings.get(0);
            }
        }
        return "";
    }
}

